package com.atguigu.jxc.service.impl;


import com.atguigu.jxc.dao.GoodsDao;
import com.atguigu.jxc.domain.ServiceVO;
import com.atguigu.jxc.domain.SuccessCode;
import com.atguigu.jxc.entity.*;

import com.atguigu.jxc.service.GoodsService;
import com.atguigu.jxc.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @description
 */
@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private GoodsDao goodsDao;
    @Autowired
    private LogService logService;

    @Override
    public ServiceVO getCode() {

        // 获取当前商品最大编码
        String code = goodsDao.getMaxCode();

        // 在现有编码上加1
        Integer intCode = Integer.parseInt(code) + 1;

        // 将编码重新格式化为4位数字符串形式
        String unitCode = intCode.toString();

        for (int i = 4; i > intCode.toString().length(); i--) {

            unitCode = "0" + unitCode;

        }
        return new ServiceVO<>(SuccessCode.SUCCESS_CODE, SuccessCode.SUCCESS_MESS, unitCode);
    }

    /**
     * 分页查询商品库存信息
     * @param page        当前页
     * @param rows        每页显示条数
     * @param codeOrName  商品编码或名称
     * @param goodsTypeId 商品类别ID
     * @return
     */
    @Override
    public Map<String, Object> listInventory(Integer page, Integer rows, String codeOrName, Integer goodsTypeId) {
        Map<String, Object> map = new HashMap<>();
        int total = 0;
        page = (page == 0 ? 1 : page);
        int offSet = (page - 1) * rows;
        List<Goods> goods = null;

        if(goodsTypeId == null) {
            //查所有
            total = goodsDao.getGoodsCount(codeOrName, goodsTypeId);
            goods = goodsDao.queryGoodsPage(offSet, rows, codeOrName, goodsTypeId);
        } else {
            //判断goodsType的state
            GoodsType goodsType = goodsDao.queryGoodsTypeById(goodsTypeId);
            if(goodsType.getGoodsTypeState() == 1) {
                //state为1 代表需要遍历
                List<GoodsTypeVO> goodsTypeVOS = queryGoodsType(goodsTypeId);
                List<Integer> goodIdList = new ArrayList<>();
                getGoodsIdList(goodsTypeVOS,goodIdList);
                total = goodIdList.size();
                goods = goodsDao.queryGoodsPage2(offSet, rows, codeOrName, goodIdList);
            } else {
                //state为0 直接查询
                total = goodsDao.getGoodsCount(codeOrName, goodsTypeId);
                goods = goodsDao.queryGoodsPage(offSet, rows, codeOrName, goodsTypeId);
            }
        }
        map.put("total", total);
        map.put("rows", goods);
        logService.save(new Log(Log.SELECT_ACTION, "分页查询当前库存"));
        return map;
    }

    private List<Integer> getGoodsIdList(List<GoodsTypeVO> goodsTypeVOS,List<Integer> goodIdList) {
        for (GoodsTypeVO goodsTypeVO : goodsTypeVOS) {
            if((Integer)goodsTypeVO.getAttributes().get("state") != 1) {
                goodIdList.add(goodsTypeVO.getId());
            } else {
                getGoodsIdList(goodsTypeVO.getChildren(),goodIdList);
            }
        }
        return goodIdList;

    }

    /**
     * 查询所有商品单位
     * @return
     */
    @Override
    public Map<String, Object> getUnitList() {
        Map<String, Object> map = new HashMap<>();
        List<Unit> units = goodsDao.getUnitList();
        map.put("rows", units);
        logService.save(new Log(Log.SELECT_ACTION, "查询所有商品单位"));
        return map;
    }

    /**
     * 分页查询商品信息
     * @param page        当前页
     * @param rows        每页显示条数
     * @param goodsName   商品名称
     * @param goodsTypeId 商品类别ID
     * @return
     */
    @Override
    public Map<String, Object> queryGoodsList(Integer page, Integer rows, String goodsName, Integer goodsTypeId) {
        Map<String, Object> map = new HashMap<>();
        int total = 0;
        page = (page == 0 ? 1 : page);
        int offSet = (page - 1) * rows;
        List<Goods> goods = null;

        if(goodsTypeId == null) {
            //查所有
            total = goodsDao.getGoodsCount(goodsName, goodsTypeId);
            goods = goodsDao.queryGoodsPage(offSet, rows, goodsName, goodsTypeId);
        } else {
            //判断goodsType的state
            GoodsType goodsType = goodsDao.queryGoodsTypeById(goodsTypeId);
            if(goodsType.getGoodsTypeState() == 1) {
                //state为1 代表需要遍历
                List<GoodsTypeVO> goodsTypeVOS = queryGoodsType(goodsTypeId);
                List<Integer> goodIdList = new ArrayList<>();
                getGoodsIdList(goodsTypeVOS,goodIdList);
                total = goodIdList.size();
                goods = goodsDao.queryGoodsPage2(offSet, rows, goodsName, goodIdList);
            } else {
                //state为0 直接查询
                total = goodsDao.getGoodsCount(goodsName, goodsTypeId);
                goods = goodsDao.queryGoodsPage(offSet, rows, goodsName, goodsTypeId);
            }
        }
        map.put("total", total);
        map.put("rows", goods);
        logService.save(new Log(Log.SELECT_ACTION, "分页查询商品信息"));
        return map;
    }

    /**
     * 查询出所有的分类
     * @return
     */
    @Override
    public List<GoodsTypeVO> loadGoodsType() {
        //1.查询出所有分类
        List<GoodsTypeVO> goodsTypeVOS = queryGoodsType(-1);
        logService.save(new Log(Log.SELECT_ACTION, "分页查询所有商品分类"));
        // return JSONArray.toJSONString(goodsTypeVOS);
        return goodsTypeVOS;
    }

    public List<GoodsTypeVO> queryGoodsType(Integer pId) {
        //1.先查询出List<GoodsType                                                >
        List<GoodsType> goodsTypes = goodsDao.queryGoodsType(pId);

        //第二次可以查出来4个对象

        if (CollectionUtils.isEmpty(goodsTypes)) {
            return null;
        }

        //2.把List<GoodsType> 转化为 List<GoodsTypeVO>
        List<GoodsTypeVO> goodsTypeVOS = new ArrayList<>();
        for (GoodsType goodsType : goodsTypes) {
            GoodsTypeVO goodsTypeVO = new GoodsTypeVO();
            goodsTypeVO.setId(goodsType.getGoodsTypeId());
            goodsTypeVO.setText(goodsType.getGoodsTypeName());
            goodsTypeVO.setState(goodsType.getGoodsTypeState() == 1 ? "closed" : "open");
            goodsTypeVO.setIconCls("goods-type");
            Map map = new HashMap();
            map.put("state", goodsType.getGoodsTypeState());
            goodsTypeVO.setAttributes(map);
            goodsTypeVOS.add(goodsTypeVO);

            if (goodsType.getGoodsTypeState() == 1) {
                //设置children
                goodsTypeVO.setChildren(queryGoodsType(goodsType.getGoodsTypeId())); //
            }
        }
        // System.out.println("list = " + goodsTypeVOS);
        return goodsTypeVOS;
    }


    /**
     * 新增商品分类
     * @param goodsTypeName
     * @param pId
     * @return
     */
    @Override
    @Transactional
    public boolean saveGoodsType(String goodsTypeName, Integer pId) {
        //1.先添加
        GoodsType goodsType = new GoodsType(goodsTypeName, 0, pId);
        int insert = goodsDao.saveGoodsType(goodsType);

        //2.判断其父类是否为叶子节点，如果是，则改变其状态
        GoodsType existGoodsType = goodsDao.queryGoodsTypeById(pId);
        if (existGoodsType.getGoodsTypeState() != 1) {
            //修改状态为1
            existGoodsType.setGoodsTypeState(1);
            goodsDao.updateGoodsTypeState(existGoodsType);
        }
        logService.save(new Log(Log.INSERT_ACTION, "新增商品分类"));
        return insert >= 1;
    }

    /**
     * 删除商品分类
     * @return
     */
    @Override
    @Transactional
    public boolean deleteGoodsType(Integer goodsTypeId) {
        //0.判断该分类下是否还有商品
        List<Goods> goodsList = goodsDao.queryGoodsPage(0, 10, null, goodsTypeId);
        if (goodsList.size() >= 1) {
            return false;
        }
        //1.先获取上一级分类信息
        GoodsType existGoodsType = goodsDao.queryGoodsTypeById(goodsTypeId);
        GoodsType parentGoodsType = goodsDao.queryGoodsTypeById(existGoodsType.getPId());
        List<GoodsType> goodsTypes = goodsDao.queryGoodsType(existGoodsType.getPId());

        //2.判断上一级分类下是否还有子分类
        if (goodsTypes.size() == 1) {
            parentGoodsType.setGoodsTypeState(0);
            goodsDao.updateGoodsTypeState(parentGoodsType);
        }

        //3.删除
        int delete = goodsDao.deleteGoodsType(goodsTypeId);

        logService.save(new Log(Log.DELETE_ACTION, "删除商品分类"));
        return delete >= 1;
    }

    /**
     * 添加或修改商品信息
     * @param goods 商品信息实体
     * @return
     */
    @Override
    public boolean saveGoods(Goods goods) {
        if (goods.getGoodsId() == null) {
            //代表为插入
            int insert = goodsDao.insertGoods(goods);
            if (insert >= 1) {
                logService.save(new Log(Log.INSERT_ACTION, "添加商品信息"));
                return true;
            }
        } else {
            int update = goodsDao.updateGoods(goods);
            if (update >= 1) {
                logService.save(new Log(Log.UPDATE_ACTION, "修改商品信息"));
                return true;
            }
        }
        return false;
    }

    /**
     * 删除商品信息
     * @param goodsId
     * @return
     */
    @Override
    public boolean deleteGoods(Integer goodsId) {
        //1.先查询
        Goods existGoods = goodsDao.queryGoodsById(goodsId);
        //2.删除，要判断state的状态
        if(existGoods.getState() == 0) {
            int delete = goodsDao.deleteGoodsById(goodsId);
            logService.save(new Log(Log.DELETE_ACTION, "删除商品信息"));
            return delete >= 1;
        }
        return false;
    }

    /**
     * 分页查询无库存商品信息
     * @param page 当前页
     * @param rows 每页显示条数
     * @param nameOrCode 商品名称或商品编码
     * @return
     */
    @Override
    public Map<String, Object> getNoInventoryQuantity(Integer page, Integer rows, String nameOrCode) {
        Map<String, Object> map = new HashMap<>();

        int total = goodsDao.getNoInventoryCount(nameOrCode);
        page = (page == 0 ? 1 : page);
        int offSet = (page - 1) * rows;
        List<Goods> goods = goodsDao.getNoInventoryQuantity(offSet, rows, nameOrCode);

        logService.save(new Log(Log.SELECT_ACTION, "分页查询无库存商品"));

        map.put("total", total);
        map.put("rows", goods);

        return map;
    }

    /**
     * 分页查询有库存商品信息
     * @param page 当前页
     * @param rows 每页显示条数
     * @param nameOrCode 商品名称或商品编码
     * @return
     */
    @Override
    public Map<String, Object> getHasInventoryQuantity(Integer page, Integer rows, String nameOrCode) {
        Map<String, Object> map = new HashMap<>();

        int total = goodsDao.getHasInventoryCount(nameOrCode);
        page = (page == 0 ? 1 : page);
        int offSet = (page - 1) * rows;
        List<Goods> goods = goodsDao.getHasInventoryQuantity(offSet, rows, nameOrCode);

        logService.save(new Log(Log.SELECT_ACTION, "分页查询有库存商品"));

        map.put("total", total);
        map.put("rows", goods);

        return map;
    }

    /**
     * 添加商品期初库存
     * @param goodsId
     * @param inventoryQuantity
     * @param purchasingPrice
     * @return
     */
    @Override
    public boolean saveStock(Integer goodsId, Integer inventoryQuantity, double purchasingPrice) {
        int update = goodsDao.saveStock(goodsId,inventoryQuantity,purchasingPrice);
        logService.save(new Log(Log.UPDATE_ACTION, "添加/修改商品期初库存"));
        return update >= 1;
    }

    /**
     * 删除商品库存
     * @param goodsId 商品ID
     * @return
     */
    @Override
    public boolean deleteStock(Integer goodsId) {
        return deleteGoods(goodsId);
    }

    /**
     * 查询库存报警商品信息
     * @return
     */
    @Override
    public Map<String, Object> listAlarm() {
        Map<String, Object> map = new HashMap<>();

        List<Goods> goodsList = goodsDao.listAlarm();
        map.put("rows",goodsList);

        logService.save(new Log(Log.SELECT_ACTION, "库存报警"));
        return map;
    }


}
